対話モードでPythonを実行して辞書データ(JSON文字列)を処理してみた
こんにちは、CX事業本部の若槻です。
AWSを利用したIoTシステムの開発で、作業の際にJSONデータを扱うことが多いため「この通常データのJSONを加工して例外データとしプログラムのテストに利用したい」「この1行のJSON文字列を整形して内容を見やすくしたい」という時がしばしばあります。
そこで今回は、そのような時にPython(対話モード)を利用してJSONデータを手元でぱぱっと処理して加工する方法を整理してみました。
基本的な使い方
まず、対話モードでPythonを実行して辞書データを扱う際の基本的な使い方を確認します。
- 最初にPythonの対話モードを開始します。
python
コマンドを実行するとプロンプトが>>>
となりpythonコードが対話式で実行可能となります。
$ python Python 3.6.8 (default, May 24 2019, 18:27:52) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
- 辞書データを作成します。冒頭で
{
と書き改行すると、Pythonは辞書データの記述が開始されたと判断して入力モード(...
というプロンプト)になり、データの内容やインデント(Tabなど)を記述できるようになる。辞書の末尾となる}
を書き改行すると入力モードは終了します。
>>> { ... "data": { ... "userId": "test1", ... "age": 28, ... "enabled": True ... } ... } {'data': {'userId': 'test1', 'age': 28, 'enabled': True}}
- 記述した辞書データを変数に代入することもできます。
>>> data = { ... "data": { ... "userId": "test1", ... "age": 28, ... "enabled": True ... } ... } >>> data {'data': {'userId': 'test1', 'age': 28, 'enabled': True}}
- 変数の型は辞書データなので
dict
となります。
>>> type(data) <class 'dict'>
- 辞書データなので添字により要素の値へアクセスすることができます。
>>> data['data']['age'] 28
append
とextend
で辞書のリストを扱う
辞書データはappend
やextend
によりリストのメンバーとして扱うこともできます。
append
を使うと辞書をリストに追加することができます。
>>> datas = [] >>> data = { ... "data": { ... "userId": "test1", ... "age": 28, ... "enabled": True ... } ... } >>> datas.append(data) >>> datas [{'data': {'userId': 'test1', 'age': 28, 'enabled': True}}] >>> data2 = { ... "data": { ... "userId": "test2", ... "age": None, ... "enabled": False ... } ... } >>> datas.append(data2) >>> datas [{'data': {'userId': 'test1', 'age': 28, 'enabled': True}}, {'data': {'userId': 'test2', 'age': None, 'enabled': False}}]
- 辞書のリストなのでデータ型は
list
となります。
>>> type(datas) <class 'list'>
- リストなのでメンバーに添字でアクセスすることができます。
>>> datas[0] {'data': {'userId': 'test1', 'age': 28, 'enabled': True}}
extend
によりリスト同士を結合することもできます。
>>> datas2 = [ ... { ... "data": { ... "userId": "test3", ... "enabled": False ... } ... } ... ] >>> datas [{'data': {'userId': 'test1', 'age': 28, 'enabled': True}}, {'data': {'userId': 'test2', 'age': None, 'enabled': False}}] >>> datas.extend(datas2) >>> datas [{'data': {'userId': 'test1', 'age': 28, 'enabled': True}}, {'data': {'userId': 'test2', 'age': None, 'enabled': False}}, {'data': {'userId': 'test3', 'enabled': False}}]
json
モジュールによるデータの変換(json.dumps
とjson.loads
)
json
モジュールを利用することにより、辞書データのJSONシリアライズや、JSON文字列のJSONデシリアライズなど、辞書データとJSON文字列間の変換を行うことができます。
json.dumps
を使うと辞書データを文字列化(JSONシリアライズ)することができます。しかし、単にjson.dumps(data)
とすると日本語などのダブルバイト文字はUnicode文字列で出力されてしまいます。
>>> data = { ... "data": { ... "userId": "てすと1", ... "age": 28 ... } ... } >>> import json >>> json.dumps(data) '{"data": {"userId": "\\u3066\\u3059\\u30681", "age": 28}}'
- そこで
json.dumps
のensure_ascii
オプションにFalse
を指定することにより日本語のまま出力することができます。
>>> json.dumps(data, ensure_ascii=False) '{"data": {"userId": "てすと1", "age": 28}}'
- さらに
json.dumps
のindent
オプションにインデント数を指定してprint
に指定することにより、整形されたJSON文字列として辞書データを出力することができます。
>>> print(json.dumps(data, ensure_ascii=False, indent=4)) { "data": { "userId": "てすと1", "age": 28 } }
- JSONシリアライズされたデータ(JSON文字列)の型は
str
です。
>>> type(json.dumps(data)) <class 'str'>
- JSONシリアライズされたデータ(JSON文字列)は
json.loads
により辞書データに変換(JSONデシリアライズ)することができます。
>>> import json >>> data = '{"data": {"userId": "test1", "age": 28, "enabled": true}}' >>> data '{"data": {"userId": "test1", "age": 28, "enabled": true}}' >>> json.loads(data) {'data': {'userId': 'test1', 'age': 28, 'enabled': True}} >>> type(json.loads(data)) <class 'dict'>
エラーとなる不正な辞書データ
辞書データとして正しくない記述をするとPythonが解釈をできないためエラーとなります。エラーとなる例を示します。
- 文字列であるにも関わらず
"
で囲われていない(userId
の値test1
)場合はNameErrorとなります。
>>> { ... "data": { ... "userId": test1, ... "age": 28, ... "enabled": True ... } ... } Traceback (most recent call last): File "<stdin>", line 3, in <module> NameError: name 'test1' is not defined
true
はBoolean型の値として使えないためNameErrorとなります。(True
やFalse
と記述するのが正しい。)
>>> { ... "data": { ... "userId": "test1", ... "age": 28, ... "enabled": true ... } ... } Traceback (most recent call last): File "<stdin>", line 5, in <module> NameError: name 'true' is not defined
Null
やnull
はNone型の値として使えないためNameErrorとなります。(None
と記述するのが正しい。)
>>> { ... "data": { ... "userId": "test1", ... "age": Null, ... "enabled": True ... } ... } Traceback (most recent call last): File "<stdin>", line 4, in <module> NameError: name 'Null' is not defined
- あるべき場所(
"age": 28
の末尾)にカンマ,
がない場合は入力途中でSyntaxErrorとなります。
>>> { ... "data": { ... "userId": "test1", ... "age": 28 ... "enabled": True File "<stdin>", line 5 "enabled": True ^ SyntaxError: invalid syntax
おわりに
今回は対話モードでPythonを実行して辞書データ(JSON文字列)を処理する方法を確認しました。
普段はPythonをコードの中でスクリプトとして記述して使うことがほとんどのため、いざ対話式で使うとなると「どう書けばいいんだっけ?」となることが多かったため、今回このような記事を書いて整理するに至りました。
以上